package tools

import (
	"bufio"
	"context"
	"crypto/md5"
	"fmt"
	_ "github.com/gogf/gf/contrib/nosql/redis/v2"
	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/text/gregex"
	"io"
	"math"
	"os"
	"seawolf-admin-go/utility/response"
)

// 不需要登录的url
func GetAdminNoLoginUrl() []string {
	// 写正则表达式
	return []string{
		"^/open/\\w+$",
	}
}

// 获取不需要权限的url
func GetAdminNoPermissionUrl() []string {
	// 写正则表达式
	return []string{
		"^/open/\\w+$",
		"/admin/permmenu$",
		"/admin/logout$",
	}
}

func RegexpContains(arr []string, str string) bool {
	for _, v := range arr {
		if gregex.IsMatchString(v, str) {
			return true
		}
	}
	return false
}

func SetAdminIdByRequest(r *ghttp.Request, adminId int64) {
	r.SetCtxVar("admin_id", adminId)
}
func GetAdminIdByRequest(r *ghttp.Request) int64 {
	return r.GetCtxVar("admin_id", 0).Int64()
}

func EncryptPassword(password string, passwordSalt string) string {
	pmd5, _ := gmd5.EncryptString(password)
	psmd5, _ := gmd5.EncryptString(passwordSalt)

	rmd5, _ := gmd5.EncryptString(pmd5 + psmd5)

	return rmd5
}

// EncryptPasswordHash 传入密码是已经经过md5加密了
func EncryptPasswordHash(password string, passwordSalt string) string {
	psmd5, _ := gmd5.EncryptString(passwordSalt)

	rmd5, _ := gmd5.EncryptString(password + psmd5)

	return rmd5
}

// 获取分页信息
func GetPageInfo(totalRows int, pageIndex int, pageSize int) response.PageInfo {
	// 需要转换为 float64
	totalPage := int(math.Ceil(float64(totalRows) / float64(pageSize)))
	return response.PageInfo{
		HasMore:     totalPage > pageIndex,
		PageIndex:   pageIndex,
		PageSize:    pageSize,
		TotalPage:   totalPage,
		TotalCount:  totalRows,
		IsFirstPage: pageIndex < 2,
		IsLastPage:  pageIndex > totalPage,
	}
}

func ClaerCacheByKeyPrefix(ctx context.Context, keyPrefix string) {
	doVar, err := g.Redis().Do(ctx, "keys", keyPrefix)
	if err != nil {
		fmt.Println(err)
		return
	}
	if doVar == nil {
		return
	}
	if len(doVar.Array()) < 1 {
		return
	}
	_, err = g.Redis().Do(ctx, "DEL", doVar.Array()...)
	if err != nil {
		fmt.Println("ClaerCacheByKeyPrefix error :", err)
		return
	}
}

func ClaerCacheByKey(ctx context.Context, key string) {
	_, err := g.Redis().Do(ctx, "DEL", key)
	if err != nil {
		fmt.Println("ClaerCacheByKey error :", err)
		return
	}
}

// PathExists 判断文件或文件夹是否存在
func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

// RemoveDuplicatesAndEmpty 数组去重 去空
func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
	a_len := len(a)
	for i := 0; i < a_len; i++ {
		if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
			continue
		}
		ret = append(ret, a[i])
	}
	return
}

func GetIconByExtension(extension string) string {
	profix := "sc-icon-doctype-"
	switch extension {
	case "doc", "docx":
		return profix + "word"
	case "xls", "xlsx":
		return profix + "excel"
	case "ppt", "pptx":
		return profix + "ppt"
	case "pdf":
		return profix + "pdf"
	case "txt":
		return profix + "txt"
	case "zip", "rar", "7z":
		return profix + "zip"
	case "jpg", "jpeg", "png", "gif":
		return profix + "image"
	default:
		return profix + "unknown"
	}
}

func FileMD5sum(filename string) (string, error) {
	bufferSize := 2097152 // 2MB 切割大小
	info, err := os.Stat(filename)
	if err != nil {
		return "", err
	} else if info.IsDir() {
		return "", nil
	}

	file, err := os.Open(filename)
	if err != nil {
		return "", err
	}
	defer file.Close()

	hash := md5.New()
	for buf, reader := make([]byte, bufferSize), bufio.NewReader(file); ; {
		n, err := reader.Read(buf)
		if err != nil {
			if err == io.EOF {
				break
			}
			return "", err
		}

		hash.Write(buf[:n])
	}

	checksum := fmt.Sprintf("%x", hash.Sum(nil))
	return checksum, nil
}
